from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response

from ERP_5.utils.base_views import MultipleDestroyMixin, MultipleAuditMixin
from ERP_5.utils.paginations import GlobalPagination
from production_info.models import ProductTaskModel
from production_info.serializer.product_task_serializer import ProductTaskSerializer, GetMaterialSerializer, \
    BackMaterialSerializer, ProductStorageSerializer


class ProductTaskViewSets(viewsets.ModelViewSet, MultipleDestroyMixin, MultipleAuditMixin):
    """
    create:
    生产任务--新增,注意：如果有BOM表，则直接读取BOM。如果没有需要自己添加生产物料和工序

    生产任务新增, status: 201(成功), return: 新增生产任务信息

    destroy:
    生产任务--删除

    生产任务删除, status: 204(成功), return: None

    multiple_delete:
    生产任务--批量删除,必传参数：ids=[1,2,3,4...]

    生产任务批量删除, status: 204(成功), return: None

    update:
    生产任务--修改,注意：其中images_list="1,2,3,4";里面是附件的ID

    生产任务修改, status: 200(成功), return: 修改后的生产任务信息

    partial_update:
    生产任务--局部修改,可以传参任意属性的值，服务器会修改指定的属性值

    生产任务局部修改, status: 200(成功), return: 修改后的生产任务信息

    list:
    生产任务--该接口可以弃用

    生产任务列表信息, status: 200(成功), return: 生产任务信息列表

    retrieve:
    查询某一个生产任务

    查询指定ID的生产任务, status: 200(成功), return: 用户生产任务
    """

    queryset = ProductTaskModel.objects.all()
    serializer_class = ProductTaskSerializer
    pagination_class = GlobalPagination

    def get_queryset(self):
        if self.action == 'find':  # 过滤查询
            # 获取请求参数(在json中)：
            number_code = self.request.data.get('number_code', None)
            keyword = self.request.data.get('keyword', None)
            start_date = self.request.data.get('start_date', None)
            end_date = self.request.data.get('start_date', None)
            query = Q()
            if keyword:
                child_query = Q()
                child_query.add(Q(name__contains=keyword), 'OR')
                child_query.add(Q(specification=keyword), 'OR')
                query.add(child_query, 'AND')
            if start_date:
                query.add(Q(invoices_date__gt=start_date), 'AND')
            if end_date:
                query.add(Q(invoices_date__lt=end_date), 'AND')
            if number_code:
                query.add(Q(number_code__contains=number_code), 'AND')

            return ProductTaskModel.objects.filter(query).distinct().all()
        else:
            return ProductTaskModel.objects.all()

    params = openapi.Schema(type=openapi.TYPE_OBJECT, properties={
        'keyword': openapi.Schema(type=openapi.TYPE_STRING, description="名称的关键字或者型号"),
        'start_date': openapi.Schema(type=openapi.TYPE_STRING, description="起始日期2020-10-01"),
        'number_code': openapi.Schema(type=openapi.TYPE_STRING, description="编号(序列号)"),
        'end_date': openapi.Schema(type=openapi.TYPE_STRING, description="结束日期2020-10-01")
    })
    # 分页参数必须是query_param(看源码)
    page_param = openapi.Parameter(name='page', in_=openapi.IN_QUERY, description="页号", type=openapi.TYPE_INTEGER)
    size_param = openapi.Parameter(name='size', in_=openapi.IN_QUERY, description="每页显示数量",
                                   type=openapi.TYPE_INTEGER)

    @swagger_auto_schema(method='POST', request_body=params, manual_parameters=[page_param, size_param],
                         operation_description="生产任务的搜索过滤")
    @action(methods=['POST'], detail=False)
    def find(self, request, *args, **kwargs):
        return super(ProductTaskViewSets, self).list(request=request, *args, **kwargs)

    @swagger_auto_schema(method='POST', request_body=GetMaterialSerializer,
                         operation_description="生产任务中领取物料")
    @action(methods=['POST'], detail=False)
    def get_material(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        result = serializer.save()
        return Response({'msg': 'ok'})

    def get_serializer_class(self):
        if self.action == 'get_material':
            return GetMaterialSerializer
        elif self.action == 'back_material':
            return BackMaterialSerializer
        elif self.action == 'product_storage':
            return ProductStorageSerializer
        else:
            return ProductTaskSerializer

    @swagger_auto_schema(method='POST', request_body=BackMaterialSerializer,
                         operation_description="生产任务中退还物料")
    @action(methods=['POST'], detail=False)
    def back_material(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        result = serializer.save()
        return Response({'msg': 'ok'})

    @swagger_auto_schema(method='POST', request_body=ProductStorageSerializer,
                         operation_description="生产任务中的生产入库")
    @action(methods=['POST'], detail=False)
    def product_storage(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        result = serializer.save()
        return Response({'msg': 'ok'})